#include <sys/mman.h>
#include <sys/stat.h>
#include <libgen.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "command.h"
#include "queue.h"

void start_sub_rqueue(int index)
{
	if(1 == rqueue_read_continue(index))
		sprintf(control->detail, "NO. %d rqueue start.\n", index);
	else
		sprintf(control->detail, "NO. %d rqueue start failed.\n", index);	
}

void stop_sub_rqueue (int index)
{
	if(rqueue_lock[index] == 1) 
	{
		sprintf(control->detail, "NO. %d rqueue already stop.\n", index);
	}
	else
	{
		rqueue_lock[index] = 1;
		if(is_rqueue_lock[index] == 1) rqueue_read_unlock(index);
	}	
}

#define PRINT_BORDER(ptr) sprintf(ptr, "+-----------+-----------+-----------+-------+-------+---------+------------+\n");
#define MOVE_TO_END(ptr) ptr += strlen(ptr);
int cmd_call_back()
{
	int i;
	struct stat buf;
	char *ptr = control->detail;
	
	switch(control->cmd)
	{
	case CMD_STOP_HTTP   :
		stop_sub_rqueue (0); break;
	case CMD_START_HTTP  :
		start_sub_rqueue(0); break;
	case CMD_STOP_SHM    :
		stop_sub_rqueue (1); break;
	case CMD_START_SHM   :
		start_sub_rqueue(1); break;	
	case CMD_STOP_MSG    :
		stop_sub_rqueue (2); break;
	case CMD_START_MSG   :
		start_sub_rqueue(2); break;
	case CMD_STOP_FIFO   :
		stop_sub_rqueue (3); break;
	case CMD_START_FIFO  :
		start_sub_rqueue(3); break;
	case CMD_STOP_DB     :
		stop_sub_rqueue (4); break;
	case CMD_START_DB    :
		start_sub_rqueue(4); break;
	case CMD_STOP_INNER  :
		stop_sub_rqueue (5); break;
	case CMD_START_INNER :
		start_sub_rqueue(5); break;
	case CMD_STOP_EXTER  :
		stop_sub_rqueue (6); break;
	case CMD_START_EXTER :
		start_sub_rqueue(6); break;
		
	case CMD_INFO:
		sprintf(ptr, "\nQueue root: %s\n", queue_root);
		MOVE_TO_END(ptr)
		char* path = strdup(handler[0].name);
		sprintf(ptr, "Queue data path: %s\n\n", dirname(path));
		free(path);
		MOVE_TO_END(ptr)
		PRINT_BORDER(ptr)
		MOVE_TO_END(ptr)
		sprintf(ptr, "|  Queue No.|    Write P|     Read P| R Lock|   Lock| File idx|        File|\n");
		MOVE_TO_END(ptr)
		PRINT_BORDER(ptr)
		MOVE_TO_END(ptr)
		for(i = 0; i < HANDLER_NUMBER; i++)
		{
			fstat(handler[i].rfd, &buf);
			sprintf(ptr, "|%11d|%11d|%11d|%7d|%7d|%9d|%12s|\n",
				 i,
				 (int)buf.st_size,
				 status[i]->position ,
				 rqueue_lock[i],
				 status[i]->is_lock,
				 status[i]->id_now,
				 strrchr(handler[i].name, '/') + 1
			);
				 
			MOVE_TO_END(ptr)
		}
	
		PRINT_BORDER(ptr)
		MOVE_TO_END(ptr)
		sprintf(ptr, "\nBy jianyu. httpqueue@sina.com. see http://www.httpqueue.com for detail.\n\n");
		break;
		
	case CMD_STOP:		
		strcpy(control->detail, "http stoped.\n");
		break;
	
	default:
		break;
	}
	
	control->cmd = CMD_NULL;
	return msync(control, sizeof(control), MS_SYNC);
}
